<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>手写一个JS函数柯里化和反柯里化</title>
</head>

<body>
    <div>
        <h3>柯里化函数的定义：将多参数的函数转换成单参数的形式。</h3>
        <h3>柯里化函数实现的原理：利用闭包原理在执行可以形成一个不销毁的作用域，</h3>
        <h3>然后把需要预先处理的内容都储存在这个不销毁的作用域中，并且返回一个最少参数函数。</h3>
        <h3></h3>
        <h3></h3>
    </div>
</body>

</html>
<script>
    /**
   * 将函数柯里化
   * @param fn    待柯里化的原函数
   * @param len   所需的参数个数，默认为原函数的形参个数
   */
    function curry(fn, len = fn.length) {
        return _curry.call(this, fn, len)
    }

    /**
     * 中转函数
     * @param fn    待柯里化的原函数
     * @param len   所需的参数个数
     * @param args  已接收的参数列表
     */
    function _curry(fn, len, ...args) {
        return function (...params) {
            let _args = [...args, ...params];
            if (_args.length >= len) {
                return fn.apply(this, _args);
            } else {
                return _curry.call(this, fn, len, ..._args)
            }
        }
    }

    let _fn = curry(function (a, b, c, d, e) {
        console.log(a, b, c, d, e)
    });


    _fn(1, 2, 3, 4, 5);     // print: 1,2,3,4,5
    _fn(1)(3)(3, 4, 5);   // print: 1,2,3,4,5
    _fn(1, 2)(3, 4)(5);   // print: 1,2,3,4,5
    _fn(1)(2)(3)(4)(5); // print: 1,2,3,4,5

</script>